package cn.stylefeng.guns.modular.gridsystem.service.impl;

import cn.hutool.core.bean.BeanUtil;
import cn.hutool.core.convert.Convert;
import cn.hutool.core.date.DateUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.stylefeng.guns.core.factory.PageFactory;
import cn.stylefeng.guns.core.pojo.page.PageResult;
import cn.stylefeng.guns.core.util.PoiUtil;
import cn.stylefeng.guns.modular.gridsystem.entity.*;
import cn.stylefeng.guns.modular.gridsystem.mapper.BizDeviceStatusAssessMapper;
import cn.stylefeng.guns.modular.gridsystem.model.param.BizDeviceStatusAssessParam;
import cn.stylefeng.guns.modular.gridsystem.model.result.BizDeviceExceptionRecordResult;
import cn.stylefeng.guns.modular.gridsystem.model.result.BizExceptionResult;
import cn.stylefeng.guns.modular.gridsystem.model.result.DeviceStatusAssessInfoResult;
import cn.stylefeng.guns.modular.gridsystem.service.*;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.*;

/**
 * 通道类型 服务实现类
 *
 * @author ssy
 * @date 2022/02/16 10:59
 */
@Slf4j
@Service
public class BizDeviceStatusAssessServiceImpl extends ServiceImpl<BizDeviceStatusAssessMapper, BizDeviceStatusAssess> implements BizDeviceStatusAssessService {


    @Resource
    private BizDeviceService bizDeviceService;
    @Resource
    private BizDeviceStatusAssessInfoService bizDeviceStatusAssessInfoService;
    @Resource
    private BizUploadScoreService bizUploadScoreService;
    @Resource
    private BizExceptionService bizExceptionService;
    @Resource
    private BizExceptionLogService bizExceptionLogService;

    /**
     * 分页查询通道类型
     *
     * @param bizDeviceStatusAssessParam
     * @return
     */
    @Override
    public PageResult<Map<String, Object>> page(BizDeviceStatusAssessParam bizDeviceStatusAssessParam) {

        // 构造条件
        LambdaQueryWrapper<BizDeviceStatusAssess> queryWrapper = new LambdaQueryWrapper<>();
        if (bizDeviceStatusAssessParam != null && ObjectUtil.isNotEmpty(bizDeviceStatusAssessParam.getDeviceId())) {
            queryWrapper.eq(BizDeviceStatusAssess::getDeviceId, bizDeviceStatusAssessParam.getDeviceId());
        }
        Integer[] list = new Integer[1];
        if (bizDeviceStatusAssessParam != null && ObjectUtil.isNotEmpty(bizDeviceStatusAssessParam.getDeviceIds())) {
            String gatewayIds = bizDeviceStatusAssessParam.getDeviceIds();
            if (StringUtils.isNotBlank(gatewayIds)) {
                String[] split = gatewayIds.split(",");
                list = Convert.toIntArray(split);
            }
        } else {
            list[0] = 0;
        }
        queryWrapper.in(BizDeviceStatusAssess::getDeviceId, list);
        // 查询分页结果
        return new PageResult<>(this.baseMapper.page(PageFactory.defaultPage(), queryWrapper));
    }

    /**
     * 查询所有通道类型
     *
     * @param bizDeviceStatusAssessParam
     * @return
     */
    @Override
    public List<BizDeviceStatusAssess> list(BizDeviceStatusAssessParam bizDeviceStatusAssessParam) {
        // 构造条件
        LambdaQueryWrapper<BizDeviceStatusAssess> queryWrapper = new LambdaQueryWrapper<>();
        if (bizDeviceStatusAssessParam != null && ObjectUtil.isNotEmpty(bizDeviceStatusAssessParam.getDeviceId())) {
            queryWrapper.eq(BizDeviceStatusAssess::getDeviceId, bizDeviceStatusAssessParam.getDeviceId());
        }
        return this.list(queryWrapper);
    }

    /**
     * 新增通道类型
     *
     * @param bizDeviceStatusAssessParam
     * @return
     */
    @Override
    public Integer add(BizDeviceStatusAssessParam bizDeviceStatusAssessParam) {
        // 将dto转为实体
        BizDeviceStatusAssess bizDeviceStatusAssess = new BizDeviceStatusAssess();
        BeanUtil.copyProperties(bizDeviceStatusAssessParam, bizDeviceStatusAssess);
        save(bizDeviceStatusAssess);
        return bizDeviceStatusAssess.getId();
    }

    /**
     * 删除通道类型
     *
     * @param bizDeviceStatusAssessParam
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void delete(BizDeviceStatusAssessParam bizDeviceStatusAssessParam) {
        //删除子设备状态评估信息
        final LambdaQueryWrapper<BizDeviceStatusAssessInfo> infoWrapper = new LambdaQueryWrapper<>();
        infoWrapper.eq(BizDeviceStatusAssessInfo::getAssessId, bizDeviceStatusAssessParam.getId());
        bizDeviceStatusAssessInfoService.remove(infoWrapper);
        removeById(bizDeviceStatusAssessParam.getId());
    }

    /**
     * 修改通道类型
     *
     * @param bizDeviceStatusAssessParam
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public void edit(BizDeviceStatusAssessParam bizDeviceStatusAssessParam) {
        // 根据id查询实体
        BizDeviceStatusAssess bizDeviceStatusAssess = this.queryBizDeviceStatusAssess(bizDeviceStatusAssessParam);
        // 请求参数转化为实体
        BeanUtil.copyProperties(bizDeviceStatusAssessParam, bizDeviceStatusAssess);
        updateById(bizDeviceStatusAssess);
    }

    /**
     * 设备状态评估详情
     *
     * @param bizDeviceStatusAssessParam
     * @return
     */
    @Override
    public BizDeviceStatusAssess detail(BizDeviceStatusAssessParam bizDeviceStatusAssessParam) {
        return queryBizDeviceStatusAssess(bizDeviceStatusAssessParam);
    }

    /**
     * 设备状态评估_导出
     *
     * @param bizDeviceStatusAssessParam 被导出信息ID
     */
    @Override
    public void export(BizDeviceStatusAssessParam bizDeviceStatusAssessParam) {
        Integer assessParamId = bizDeviceStatusAssessParam.getId();
        LambdaQueryWrapper<BizDeviceStatusAssessInfo> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(BizDeviceStatusAssessInfo::getAssessId, assessParamId);
        queryWrapper.last("limit 1");
        BizDeviceStatusAssessInfo bizDeviceStatusAssessInfo = bizDeviceStatusAssessInfoService.getOne(queryWrapper);
        if (ObjectUtil.isNotNull(bizDeviceStatusAssessInfo)) {
            String exceptionIds = bizDeviceStatusAssessInfo.getExceptionIds();
            String[] arr1 = exceptionIds.split(", "); // removes the brackets and splits the string into an array
            if (arr1.length > 0) {
                String[] arr = arr1[0].split(",");

                int[] intArr = new int[arr.length];
                for (int i = 0; i < arr.length; i++) {
                    intArr[i] = Integer.parseInt(arr[i]); // converts each string element to an integer
                }
                List<DeviceStatusAssessInfoResult> assessInfoList = bizDeviceStatusAssessInfoService.getAssessInfoList(intArr);
                PoiUtil.exportExcelWithStream("设备状态评估报告.xls", DeviceStatusAssessInfoResult.class, assessInfoList);
            }

        }
    }

    /**
     * 获取通道类型
     *
     * @author ssy
     * @since 2022/02/16 10:59
     */
    private BizDeviceStatusAssess queryBizDeviceStatusAssess(BizDeviceStatusAssessParam bizDeviceStatusAssessParam) {
        return this.getById(bizDeviceStatusAssessParam.getId());
    }

    /**
     * 设备状态评估_自定义导出
     *
     * @param stationId
     * @param deviceId
     * @param startTime
     * @param endTime
     */
    @Override
    public void exportCustom(Integer stationId, Integer deviceId, String startTime, String endTime) {

        List<BizDeviceExceptionRecordResult> recordResults = bizDeviceService.getDeviceException(stationId, startTime, endTime);
        List<DeviceStatusAssessInfoResult> assessInfoList = new ArrayList<>();
        for (BizDeviceExceptionRecordResult result : recordResults) {
            BizDeviceStatusAssessParam param = new BizDeviceStatusAssessParam();
            param.setDeviceId(result.getDeviceId());
            param.setErrorNumber(result.getUnprocessedRecords());
            param.setNormalNumber(result.getProcessedRecords());
            param.setAssessTime(DateUtil.date());
            param.setType(3);
            if (ObjectUtil.isEmpty(deviceId)) {
                List<BizExceptionResult> results = bizExceptionService.getDeviceExceptionList(stationId, 0, startTime, endTime);
                Set<Integer> exceptIds = new HashSet<>();
                for (BizExceptionResult exceptionResult : results) {
                    Integer exceptionId = exceptionResult.getExceptionId();
                    exceptIds.add(exceptionId);
                }
                int[] array = exceptIds.stream().mapToInt(Integer::intValue).toArray();
                assessInfoList = bizDeviceStatusAssessInfoService.getAssessInfoList(array);
                PoiUtil.exportExcelWithStream("设备状态评估报告.xls", DeviceStatusAssessInfoResult.class, assessInfoList);
                return;
            } else {
                if (deviceId.equals(result.getDeviceId())) {
                    List<BizExceptionResult> results = bizExceptionService.getDeviceExceptionList(stationId, deviceId, startTime, endTime);
                    Set<Integer> exceptIds = new HashSet<>();
                    for (BizExceptionResult exceptionResult : results) {
                        Integer exceptionId = exceptionResult.getExceptionId();
                        exceptIds.add(exceptionId);
                    }
                    int[] array = exceptIds.stream().mapToInt(Integer::intValue).toArray();
                    assessInfoList = bizDeviceStatusAssessInfoService.getAssessInfoList(array);
                    PoiUtil.exportExcelWithStream("设备状态评估报告.xls", DeviceStatusAssessInfoResult.class, assessInfoList);
                    return;
                }
            }
        }
        PoiUtil.exportExcelWithStream("设备状态评估报告.xls", DeviceStatusAssessInfoResult.class, assessInfoList);
    }

    /**
     * 查询日志表总的上传数量：正常+故障
     */
    @Override
    public void assess() {
        //查询日志表总的上传数量：正常+故障
        QueryWrapper<BizUploadScore> queryWrapper = new QueryWrapper<>();
        queryWrapper.select("count(1) as allAcount", "device_id as deviceId");
        queryWrapper.groupBy("device_id");
        List<Map<String, Object>> list = bizUploadScoreService.listMaps(queryWrapper);
        final BizDeviceStatusAssessParam bizDeviceStatusAssessParam = new BizDeviceStatusAssessParam();
        for (Map<String, Object> map : list) {
            Integer deviceId = Integer.parseInt(map.get("deviceId").toString());
            //查询设备对应故障
            final QueryWrapper<BizException> queryWrapper1 = new QueryWrapper<>();
            queryWrapper1.eq("device_id", deviceId);
            final List<BizException> exceptionList = bizExceptionService.list(queryWrapper1);
            int count = 0;
            final List<Integer> exceptionIds = new ArrayList<>();
            for (BizException bizException : exceptionList) {
                final Integer exceptionId = bizException.getId();
                //记录子主表故障关联id
                exceptionIds.add(exceptionId);
                //查询故障数量
                final QueryWrapper<BizExceptionLog> wrapper = new QueryWrapper<>();
                wrapper.eq("exception_id", exceptionId);
                count += bizExceptionLogService.count(wrapper);
            }
            //总数量
            final int allAcount = Integer.parseInt(map.get("allAcount").toString());
            bizDeviceStatusAssessParam.setNormalNumber(allAcount - count);
            bizDeviceStatusAssessParam.setErrorNumber(count);
            bizDeviceStatusAssessParam.setDeviceId(deviceId);
            bizDeviceStatusAssessParam.setAssessTime(DateUtil.date());
            //添加故障评估主表
            final Integer assessId = this.add(bizDeviceStatusAssessParam);
            log.info("添加结果assessId为：{}", assessId);
            //添加故障评估字表
            final BizDeviceStatusAssessInfo bizDeviceStatusAssessInfo = new BizDeviceStatusAssessInfo();
            bizDeviceStatusAssessInfo.setAssessId(assessId);
            bizDeviceStatusAssessInfo.setExceptionIds(StringUtils.join(exceptionIds.toArray(), ","));
            bizDeviceStatusAssessInfoService.save(bizDeviceStatusAssessInfo);
        }
    }
}
